<?php 
namespace PsiFramework\Classes\Util\Parameters\DAO;

import("Classes.Util.Parameters.DAO.ApplicationDAO");
import("Classes.Util.Parameters.DAO.ObjectParametersDAO");

use \PsiFramework\Classes\Util\Parameters\DAO\ApplicationDAO;
use \PsiFramework\Classes\Util\Parameters\DAO\ObjectParametersDAO;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The ApplicationsDAO class is the generic class
 * to retrieve all the applications
 *
 * @package Util.Parameters.DAO
 */
class ApplicationsDAO
{

    protected static $_singleton = null;

    protected /*Application[]*/ $_applications ;

    public function __construct()
    {
        $this->_applications = array();
        $this->retrieveApplications();
    }

    public function getApplications()
    {
        return $this->_applications ;
    }

    protected function retrieveApplications()
    {
        $appsDirPath = getApplicationsDirectory();
        $appsDir = opendir($appsDirPath);
        while ($entry = readdir($appsDir)) {
            if (!startsWith($entry, '.')) {
                $this->retrieveApplication($entry);
            }
        }
    }

    protected function retrieveApplication($applicationName)
    {
        if (!isset($this->_applications[$applicationName])) {
            $appConfig = getApplicationConfigDirectory($applicationName);
            if (is_dir($appConfig)) {
                $configFile = $appConfig . '/application.config.xml' ;
                if (is_file($configFile)) {
                    $applicationDao = new ApplicationDAO();
                    $applicationDao->initByFile($configFile);
                    $application = $applicationDao->retrieveApplication();

                    if (!is_null($application)) {

                        $parent = null ;
                        $parentName = $applicationDao->getParentName();

                        if (!is_null($parentName)) {
                            if (isset($this->_applications[$parentName])) {
                                $parent = $this->_applications[$parentName] ;
                            } else {
                                $this->retrieveApplication($parentName);
                                if (isset($this->_applications[$parentName])) {
                                    $parent
                                        = $this->_applications[$parentName] ;
                                } else {
                                    throw new \Exception(
                                        'The parent Application "'.$parentName.
                                        '" for Application "'.
                                        $application->getName().
                                        '" was not found.'
                                    );
                                }
                            }
                        }
                        $application->setParent($parent);
                        $this->_applications[$application->getName()]
                            = $application ;
                    }
                }
            }
        }
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return     ApplicationsDAO instance
     */
    public static function getInstance()
    {

        if (self::$_singleton==null) {
            self::$_singleton = new ApplicationsDAO();
        }

        return self::$_singleton;
    }
}
